home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / Origami / Sources / src / keybind / parser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  28.0 KB  |  801 lines

  1. /*{{{}}}*/
  2. /*{{{  #includes*/
  3. #include <ctype.h>
  4. #include <termios.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8.  
  9. #define PARSER_C
  10. #define I_SET_C
  11. #define I_RC_CHECK
  12.  
  13. #include <h/getmsg.h>
  14. #include "keybind.h"
  15. #include <h/rcformat.h>
  16. #include <h/envvar_str.h>
  17. #include <lib/ori_rc_lib.h>
  18. #include <lib/ori_add_lib.h>
  19. /*}}}  */
  20.  
  21. /*{{{  define _POSIX_VDISABLE to 0377, if bd os doesn't support*/
  22. #ifndef _POSIX_VDISABLE
  23. #  define _POSIX_VDISABLE 0377
  24. #endif
  25. /*}}}  */
  26. /*{{{  variables*/
  27. private unsigned char nullc='\0';
  28. public int bind_const[RCC_SIZE];
  29. public unsigned char ocl_opts[NO_OCL_CMD_OPTS*(2*BIND_NAME_LEN+2)];
  30. public unsigned char *op_def_name = &nullc;
  31. public int op_def_args = 0;
  32. public TOKEN *m_def;
  33. public unsigned char *modenames[MODE_COUNT];
  34. public int used_modes=0;
  35. public int vm_no=0;
  36. public int bc_mac=0;
  37. public boolean demand=False;
  38. private unsigned char *ocl_arg_names[ocl_max_args];
  39. /*}}}  */
  40.  
  41. /*{{{  check_length*/
  42. public void check_length(TOKEN *b)
  43. {
  44.   if ((b-mac_ptr)>OCL_CODE_LEN)
  45.      m_exit(M_LONG_MACRO);
  46. }
  47. /*}}}  */
  48. /*{{{  mac_arg_parse*/
  49. private int mac_arg_parse(void)
  50. { int no;
  51.  
  52.   for (no=0;no<ocl_max_args;)
  53.    { switch (get_full_token())
  54.       { case END:
  55.            if (no==0)
  56.               goto inv_arg_list;
  57.            return(no);
  58.         case VARIABLE:
  59.         case NAME:
  60.            def_ocl_args(no+1);
  61.            creat_var(tk_string,1,ocl_loc_var(no));
  62.            ocl_arg_names[no]=mstrcpy(tk_string);
  63.            no++;
  64.            continue;
  65.         default:
  66.         inv_arg_list:
  67.            m_exit(M_INV_ARGS);
  68.       }
  69.    }
  70. }
  71. /*}}}  */
  72. /*{{{  no_arg_vars*/
  73. private void no_arg_vars(int args)
  74. {
  75.   while (args--)
  76.    { free_var(ocl_arg_names[args]);
  77.      kbd_free(ocl_arg_names[args]);
  78.    }
  79. }
  80. /*}}}  */
  81. /*{{{  parse the file*/
  82. public boolean process_file(void)
  83. {
  84.   /*{{{  variables*/
  85.   tokens token;
  86.   boolean named=False;
  87.   int dem_count=0;
  88.   int n_dem_count=0;
  89.   char *opt_end;
  90.   /*}}}  */
  91.  
  92.   rc_put_w(RC_CHECK,rc.fp);
  93.   general_abort_key=_POSIX_VDISABLE;
  94.   mac_count= -1;
  95.   put_consts();
  96.   mac_count= 0;
  97.   /*{{{  init ocl options*/
  98.   opt_end=(char*)ocl_opts;
  99.   *opt_end='\0';
  100.   /*}}}  */
  101.   init_vars(def_dummy_vars);
  102.   /*{{{  parse the sources*/
  103.   err_pos_out=True;
  104.   for (;mac_count!=0x7fff;)
  105.      if ((token=get_full_token())==ENDFILE)
  106.         if (dem_count || n_dem_count)
  107.            m_exit(F_MIS_DEM_END,dem_count+n_dem_count);
  108.         else
  109.            break;
  110.      else
  111.         switch (token)
  112.          { case END:
  113.             /*{{{  handle end of demand statements*/
  114.               if (!dem_count && !n_dem_count)
  115.                  m_exit(M_NO_DEM);
  116.               if (n_dem_count)
  117.                  demand=(--n_dem_count==0 && dem_count);
  118.               else
  119.                  demand= --dem_count;
  120.               if (verbose_level>1)
  121.                  fprintf(stderr,F_DEM_COMMENT,demand?"":"not ",dem_count,n_dem_count);
  122.               goto get_end_token;
  123.             /*}}}  */
  124.            case BEGIN:
  125.             /*{{{  ocl statement*/
  126.             { token=get_full_token();
  127.               switch (token) {
  128.                 /*{{{  demand*/
  129.                 case DEMAND:
  130.                    switch(get_full_token())
  131.                     { case NOT:
  132.                          if (get_single_token()!=BEGIN)
  133.                             goto demand_error;
  134.                          n_dem_count++;
  135.                          demand=False;
  136.                          break;
  137.                       case BEGIN:
  138.                          if (n_dem_count)
  139.                             n_dem_count++;
  140.                          else
  141.                             demand= ++dem_count;
  142.                          break;
  143.                       default:
  144.                       demand_error:
  145.                          m_exit(M_WANTBEGIN);
  146.                     }
  147.                    if (verbose_level>1)
  148.                       fprintf(stderr,F_DEM_COMMENT,demand?"":"not ",dem_count,n_dem_count);
  149.                    continue;
  150.                 /*}}}  */
  151.                 /*{{{  history_declare*/
  152.                 case HISTORY:
  153.                    if (name_to_history(get_full_token(),True)==unknown_history)
  154.                 history_expected:
  155.                       m_exit(M_NOHISTORY);
  156.                    break;
  157.                 /*}}}  */
  158.                 /*{{{  shift-mark*/
  159.                 case LINESTART:
  160.                    if (get_keycode_token()!=CHAR)
  161.                       m_exit(M_WANTCHAR);
  162.                    soln_str=tk_char;
  163.                    break;
  164.                 /*}}}  */
  165.                 /*{{{  line-limiter*/
  166.                 case LINEEND:
  167.                    if (get_keycode_token()!=CHAR)
  168.                       m_exit(M_WANTCHAR);
  169.                    eoln_str=tk_char;
  170.                    break;
  171.                 /*}}}  */
  172.                 /*{{{  mode-limiter*/
  173.                 case MODE_COMMA:
  174.                    if (get_keycode_token()!=CHAR)
  175.                       m_exit(M_WANTCHAR);
  176.                    comma=tk_char;
  177.                    break;
  178.                 /*}}}  */
  179.                 /*{{{  termalias*/
  180.                 case TERMALIAS:
  181.                  { unsigned char replace[NAME_LG+1];
  182.                    tokens tn;
  183.  
  184.                    token=get_full_token();
  185.                    if (token!=NAME && token!=NUMBER)
  186.                       m_exit(M_T_NAME);
  187.                    ustrcpy(replace,tk_string);
  188.                    if (!dest_mac) rc_put_c(RC_TERMALIAS,rc.fp);
  189.                    begin_parse();
  190.                    while ((tn=get_full_token())!=END)
  191.                     { if (tn!=NAME && tn!=NUMBER)
  192.                          m_exit(M_T_NAME);
  193.                       /*{{{  print alias to rc*/
  194.                       if (!dest_mac)
  195.                        { unsigned char *s;
  196.  
  197.                          rc_put_c(1,rc.fp);
  198.                          s=tk_string;
  199.                          do rc_put_c(*s,rc.fp); while (*s++);
  200.                        }
  201.                       /*}}}  */
  202.                     }
  203.                    /*{{{  print replace to rc*/
  204.                    if (!dest_mac)
  205.                     { unsigned char *s;
  206.  
  207.                       rc_put_c(0,rc.fp);
  208.                       s=replace;
  209.                       do rc_put_c(*s,rc.fp); while (*s++);
  210.                     }
  211.                    /*}}}  */
  212.                    break;
  213.                  }
  214.                 /*}}}  */
  215.                 /*{{{  os-extension*/
  216.                 case OS_EXT:
  217.                    begin_parse();
  218.                    if (verbose_level>0)
  219.                       fprintf(stderr,M_ADD_OS_X);
  220.                    /*{{{  read all strings*/
  221.                    { if (!dest_mac)
  222.                         rc_put_c(RC_OS_EXTENSION,rc.fp);
  223.                      for (;;)
  224.                       { switch(get_full_token())
  225.                          { int no;
  226.  
  227.                            /*{{{  ) == end*/
  228.                            case END:
  229.                               break;
  230.                            /*}}}  */
  231.                            /*{{{  string*/
  232.                            case MACRO:
  233.                               if (!dest_mac)
  234.                                { TOKEN *x=tk_macro;
  235.  
  236.                                  if (verbose_level>0)
  237.                                     fprintf(stderr,(char*)tk_string);
  238.                                  while (*x)
  239.                                     rc_put_c(*x++,rc.fp);
  240.                                }
  241.                               continue;
  242.                            /*}}}  */
  243.                            /*{{{  defined function*/
  244.                            case OPERATION:
  245.                               if (!dest_mac)
  246.                                { no=tk_operation->place;
  247.                                  goto os_number;
  248.                                }
  249.                               continue;
  250.                            /*}}}  */
  251.                            /*{{{  mode*/
  252.                            case KBD:
  253.                               if ((no=token2mode(get_full_token()))<0)
  254.                                  kbd_exit(1);
  255.                               goto os_number;
  256.                            /*}}}  */
  257.                            /*{{{  history*/
  258.                            case HISTORY:
  259.                               no=name_to_history(get_full_token(),False);
  260.                               if (no==unknown_history)
  261.                                  goto history_expected;
  262.                               if (!dest_mac)
  263.                                { goto os_number;
  264.                                  /*{{{  os_number*/
  265.                                  { char *x;
  266.                                    char id[16];
  267.  
  268.                                  os_number:
  269.                                    sprintf(x=id,"%d",no);
  270.                                    while (*x)
  271.                                       rc_put_c(*x++,rc.fp);
  272.                                    if (verbose_level>0)
  273.                                       fprintf(stderr,(char*)id);
  274.                                  }
  275.                                  /*}}}  */
  276.                                }
  277.                               continue;
  278.                            /*}}}  */
  279.                            /*{{{  default error*/
  280.                            default:
  281.                               m_exit(M_WANTEND);
  282.                            /*}}}  */
  283.                          }
  284.                         break;
  285.                       }
  286.                      if (!dest_mac)
  287.                         rc_put_c(0,rc.fp);
  288.                    }
  289.                    /*}}}  */
  290.                    if (verbose_level>0) fprintf(stderr,M_END_OS_X);
  291.                    break;
  292.                 /*}}}  */
  293.                 /*{{{  terminal*/
  294.                 case TERMINAL:
  295.                    terminal_cmd();
  296.                    continue;
  297.                 /*}}}  */
  298.                 /*{{{  alias command*/
  299.                 case KEYALIAS:
  300.                    set_alias();
  301.                    break;
  302.                 /*}}}  */
  303.                 /*{{{  user-macros*/
  304.                 case DEFMYFIX:
  305.                    if (mac_count || get_full_token()!=NUMBER)
  306.                       m_exit(mac_count?M_MACGIV:M_NOADDCOUNTER);
  307.                    mac_count=tk_val;
  308.                    break;
  309.                 /*}}}  */
  310.                 /*{{{  keybind command*/
  311.                 case KEYDEF:
  312.                    def_keybind_code();
  313.                    continue;
  314.                 /*}}}  */
  315.                 /*{{{  overload prefix*/
  316.                 case OVER_PRE:
  317.                    overload_prefix();
  318.                    continue;
  319.                 /*}}}  */
  320.                 /*{{{  forward-declaration*/
  321.                 case FORWARD:
  322.                  { int args;
  323.                  
  324.                    /*{{{  check name, and maybe arguments*/
  325.                    switch (token=get_full_token())
  326.                     { case BEGIN:
  327.                          args=mac_arg_parse();
  328.                          no_arg_vars(args);
  329.                          if (get_full_token()!=NAME)
  330.                             goto f_w_e;
  331.                          else
  332.                             break;
  333.                       case NAME:
  334.                          args=0;
  335.                          break;
  336.                       default:
  337.                       f_w_e:
  338.                          m_exit(M_MACNAME);
  339.                     }
  340.                    /*}}}  */
  341.                    mac_ptr[0]=(TOKEN)((int)O_EXE_MACRO+ ++mac_count);
  342.                    mac_ptr[1]=M_END_MACRO;
  343.                    if (verbose_level>0) fprintf(stderr,F_FOR,mac_count);
  344.                    creat_op(tk_string,False,1,mac_ptr,mac_count,False,args);
  345.                    break;
  346.                  }
  347.                 /*}}}  */
  348.                 /*{{{  automacro/abortmacro/promptmacros/knb/view*/
  349.                 case DEFAUTOSAVE:
  350.                 case DEFQUIT:
  351.                 case DEFU1:
  352.                 case DEFU2:
  353.                 case DEFAUTO:
  354.                 case DEFAB:
  355.                 case KNBM:
  356.                 case PRO_IN:
  357.                 case PRO_OUT:
  358.                 case B_CHG_MAC:
  359.                 case VMAC:
  360.                  { int *x= token==DEFAUTOSAVE ? &salarm_macro:
  361.                            token==DEFQUIT  ? &squit_macro:
  362.                            token==DEFU1    ? &susr1_macro:
  363.                            token==DEFU2    ? &susr2_macro:
  364.                            token==PRO_IN   ? &pin_macro:
  365.                            token==PRO_OUT  ? &pout_macro:
  366.                            token==KNBM     ? &knb_macro:
  367.                            token==DEFAB    ? &abort_macro:
  368.                            token==VMAC     ? &view_macro:
  369.                            token==B_CHG_MAC? &buff_macro:
  370.                                              &auto_macro;
  371.  
  372.                   /*{{{  already given?*/
  373.                   if (*x)
  374.                      m_exit(M_DUPAUTO);
  375.                   /*}}}  */
  376.                   /*{{{  check if macroname given*/
  377.                   if (get_full_token()!=OPERATION || tk_operation->place<0)
  378.                      m_exit(M_INVMNAME);
  379.                   /*}}}  */
  380.                   *x=tk_operation->place;
  381.                   break;
  382.                  }
  383.                 /*}}}  */
  384.                 /*{{{  define a new operation*/
  385.                 case DEFOP:
  386.                  { boolean ret_used=False;
  387.                    TOKEN  *tl_ptr;
  388.                    unsigned char name[NAME_LG];
  389.                  
  390.                    name_parse(name,M_DEFONAME,False);
  391.                    /*{{{  prepare M_CALL-information*/
  392.                    op_def_args=0;
  393.                    op_def_name=name;
  394.                    m_def=mac_ptr;
  395.                    /*}}}  */
  396.                    if (!(tl_ptr=opt_parse_macro(mac_ptr,0,&ret_used,False,n_dem_count,False)))
  397.                      return(True);
  398.                    /*{{{  reset M_CALL-information*/
  399.                    op_def_name = &nullc;
  400.                    m_def=0;
  401.                    /*}}}  */
  402.                    creat_op(name,True,tl_ptr-mac_ptr,mac_ptr,-1,ret_used,0);
  403.                    break;
  404.                  }
  405.                 /*}}}  */
  406.                 /*{{{  macro commands*/
  407.                 case DEFASM:
  408.                 case DEFMACRO:
  409.                 case INITMACRO:
  410.                  { unsigned char name[NAME_LG];
  411.                    boolean asm_used=(token==DEFASM);
  412.                    boolean def_used=(asm_used || (token==DEFMACRO));
  413.                    boolean ret_used=False;
  414.                    boolean dest_found;
  415.                    TOKEN  *tl_ptr;
  416.                    int var_c=var_count;
  417.                    readtags tag= def_used?RC_MAC_SET:RC_INITMACRO;
  418.                    int po;
  419.                  
  420.                    /*{{{  maybe get args for deffun, get name*/
  421.                    op_def_args=0;
  422.                    switch (token)
  423.                     { case DEFMACRO:
  424.                          if ((token=get_full_token())!=BEGIN)
  425.                             break;
  426.                          op_def_args=mac_arg_parse();
  427.                       default:
  428.                          token=get_full_token();
  429.                       }
  430.                    /*}}}  */
  431.                    if (token==NAME)
  432.                     /*{{{  declaration & definition*/
  433.                     { po = ++mac_count;
  434.                       ustrcpy(name,tk_string);
  435.                       op_def_name=name;
  436.                       m_def=mac_ptr;
  437.                     }
  438.                     /*}}}  */
  439.                    else if (token==OPERATION)
  440.                     /*{{{  definition*/
  441.                     { if (tk_operation->def || (tk_operation->args!=op_def_args && !asm_used))
  442.                          m_exit(M_DUPDEF);
  443.                       ustrcpy(name,tk_operation->op_name);
  444.                       tk_operation->def=True;
  445.                       po = (int)*(tk_operation->ops)-(int)O_EXE_MACRO;
  446.                       op_def_name=name;
  447.                     }
  448.                     /*}}}  */
  449.                    else
  450.                       m_exit(M_INVMNAME);
  451.                    dest_found= dest_mac && !(ustrcmp(dest_mac,name));
  452.                    if (asm_used)
  453.                     /*{{{  get assembler code*/
  454.                     { if (!(tl_ptr=parse_asm(mac_ptr,name)))
  455.                          return(True);
  456.                     }
  457.                     /*}}}  */
  458.                    else
  459.                     /*{{{  get normal OCL code*/
  460.                     { if
  461.                        ( !(tl_ptr=opt_parse_macro
  462.                                    ( mac_ptr,
  463.                                      op_def_args,
  464.                                      &ret_used,
  465.                                      def_used,
  466.                                      !demand,
  467.                                      False
  468.                                    )
  469.                           )
  470.                        )
  471.                          return(True);
  472.                     }
  473.                     /*}}}  */
  474.                    /*{{{  store information and show verbose*/
  475.                    if (token!=OPERATION)
  476.                     /*{{{  macro as operation storing*/
  477.                     { /* create op does the verbose handling! */
  478.                       if (def_used)
  479.                        { TOKEN dummy[1];
  480.                       
  481.                          dummy[0]=(TOKEN)((int)O_EXE_MACRO+po);
  482.                          creat_op(name,True,1,dummy,po,False,op_def_args);
  483.                        }
  484.                       else
  485.                          creat_op(name,True,tl_ptr-mac_ptr,mac_ptr,po,ret_used,op_def_args);
  486.                       m_def=0;
  487.                       op_def_name = &nullc;
  488.                     }
  489.                     /*}}}  */
  490.                    else
  491.                     /*{{{  verbose*/
  492.                     { if (verbose_level>0)
  493.                          fprintf(stderr,".\n");
  494.                     }
  495.                     /*}}}  */
  496.                    /*}}}  */
  497.                    if (!asm_used)
  498.                     /*{{{  OCL code uses fixed argument commands*/
  499.                     { *tl_ptr++=M_END_MACRO;
  500.                       tl_ptr=opt_mac(mac_ptr,tl_ptr,False,False,True);
  501.                       if (tl_ptr>mac_ptr && *(tl_ptr-1)==M_END_MACRO)
  502.                          tl_ptr--;
  503.                     }
  504.                     /*}}}  */
  505.                    /*{{{  write it to rc*/
  506.                    if (dest_found && var_c==var_count)
  507.                       write_dest_mac(mac_ptr,tl_ptr-mac_ptr);
  508.                    write_macro_rc(tag,po,tl_ptr-mac_ptr,mac_ptr,name);
  509.                    /*}}}  */
  510.                    no_arg_vars(op_def_args);
  511.                    break;
  512.                  }
  513.                 /*}}}  */
  514.                 /*{{{  reference compress strings*/
  515.                 case REF_COMP:
  516.                    token=get_full_token();
  517.                    /*{{{  maybe set used*/
  518.                    if (token==SET_COUNTER)
  519.                     { ref_init_comp_data(0);
  520.                       token=get_full_token();
  521.                     }
  522.                    /*}}}  */
  523.                    /*{{{  test if ( used*/
  524.                    if (token!=BEGIN)
  525.                       m_exit(M_WANTBEGIN);
  526.                    /*}}}  */
  527.                    for (;;)
  528.                     { switch(get_full_token())
  529.                        { case END:
  530.                             break;
  531.                          case MACRO:
  532.                             if (ref_add_word((char*)tk_string))
  533.                                m_exit(M_NOMEMORY);
  534.                             continue;
  535.                          default:
  536.                             m_exit(M_REFCOMP);
  537.                        }
  538.                       break;
  539.                     }
  540.                    break;
  541.                 /*}}}  */
  542.                 /*{{{  define modes*/
  543.                 case MULTIKBD:
  544.                    define_k_modes();
  545.                    continue;
  546.                 /*}}}  */
  547.                 /*{{{  mouse*/
  548.                 case MOUSEMAP:
  549.                    mouse_code();
  550.                    continue;
  551.                 /*}}}  */
  552.                 /*{{{  mode*/
  553.                 case KBD:
  554.                    mode_code();
  555.                    continue;
  556.                 /*}}}  */
  557.                 /*{{{  define the name of this binding*/
  558.                 case BINDNAME:
  559.                  { unsigned char name[NAME_LG];
  560.  
  561.                    if (named)
  562.                       m_exit(M_DUPKEY);
  563.                    named=True;
  564.                    name_parse(name,M_KEYNAME,True);
  565.                    write_name_rc(tk_string);
  566.                    for (;;)
  567.                     { switch(get_full_token())
  568.                        { case END:
  569.                             break;
  570.                          case BEGIN:
  571.                           /*{{{  handle one ocl-option*/
  572.                             if
  573.                              /*{{{  correct option name given*/
  574.                              (    get_full_token()==MACRO
  575.                                && isalpha(tk_string[0])
  576.                                && ustrlen(tk_string)<=BIND_NAME_LEN
  577.                              )
  578.                              /*}}}  */
  579.                              /*{{{  check second string*/
  580.                              { char b[BIND_NAME_LEN+1];
  581.  
  582.                                strcpy(b,(char*)tk_string);
  583.                                if ( get_full_token()==MACRO )
  584.                                 /*{{{  define as ocl-options*/
  585.                                 { char *o;
  586.  
  587.                                   if
  588.                                    /*{{{  space left in option string*/
  589.                                    (   opt_end+strlen(b)+ustrlen(tk_string)+2
  590.                                      < (char*)ocl_opts+NO_OCL_CMD_OPTS*(2*BIND_NAME_LEN+2)
  591.                                    )
  592.                                    /*}}}  */
  593.                                    /*{{{  store it*/
  594.                                    { for
  595.                                       ( o=b
  596.                                       ; (*opt_end++ = *o++)
  597.                                       ;
  598.                                       );
  599.                                      for
  600.                                       ( o=(char*)tk_string
  601.                                       ; (*opt_end++ = *o++)
  602.                                       ;
  603.                                       );
  604.                                      *opt_end='\0';
  605.                                    }
  606.                                    /*}}}  */
  607.                                   else
  608.                                      goto o_o_err;
  609.                                   if (get_full_token()==END)
  610.                                      continue;
  611.                                 }
  612.                                 /*}}}  */
  613.                              }
  614.                              /*}}}  */
  615.                           /*}}}  */
  616.                          default:
  617.                          o_o_err:
  618.                             m_exit(M_NOOCLOPT);
  619.                        }
  620.                       break;
  621.                     }
  622.                    continue;
  623.                  }
  624.                 /*}}}  */
  625.                 /*{{{  defmark*/
  626.                 case DEFMARK:
  627.                  { int i,j;
  628.                    unsigned char marks[4][FOLD_TAG_LENGTH+1];
  629.                    unsigned char mark_name[NAME_LG];
  630.                  
  631.                    name_parse(mark_name,M_MARKNAME,True);
  632.                    /*{{{  get all mark_characters*/
  633.                    begin_parse();
  634.                    /*{{{  get all tags*/
  635.                    for (i=0;i<4;i++) {
  636.                      begin_parse();
  637.                      /*{{{  get tag_length-1 chars*/
  638.                      for (j=0;j<FOLD_TAG_LENGTH;j++)
  639.                       { if (get_keycode_token()!=CHAR)
  640.                            m_exit(M_WANTCHAR);
  641.                         marks[i][j]=tk_char;
  642.                       }
  643.                      /*}}}  */
  644.                      end_parse(M_WANTEND);
  645.                    }
  646.                    /*}}}  */
  647.                    end_parse(M_WANTEND);
  648.                    /*}}}  */
  649.                    write_mark_rc(mark_name,marks);
  650.                    break;
  651.                  }
  652.                 /*}}}  */
  653.                 /*{{{  defset*/
  654.                 case DEFSET:
  655.                    parse_set();
  656.                    break;
  657.                 /*}}}  */
  658.                 /*{{{  defvar*/
  659.                 case DEFVAR:
  660.                  { tokens to;
  661.                    int size;
  662.  
  663.                    /*{{{  parse ( and maybe set dimension*/
  664.                    switch (to=get_full_token())
  665.                     { case BEGIN:
  666.                          size=1;
  667.                          break;
  668.                       case NUMBER:
  669.                          size=tk_val;
  670.                          begin_parse();
  671.                          if (size>0)
  672.                             break;
  673.                       default:
  674.                          m_exit(M_WANTBEGIN);
  675.                     }
  676.                    /*}}}  */
  677.                    while ((to=name_to_var(get_full_token(),size,True))!=END)
  678.                       if (to!=VARIABLE)
  679.                          m_exit(M_NOVAR);
  680.                    break;
  681.                  }
  682.                 /*}}}  */
  683.                 /*{{{  undeclare*/
  684.                 case UNDECLARE:
  685.                  { tokens to;
  686.  
  687.                    begin_parse();
  688.                    while ((to=get_full_token())!=END)
  689.                     { if (verbose_level>1)
  690.                          fprintf(stderr,"undeclaring %s\n",tk_string);
  691.                       switch (to)
  692.                        { case OPERATION:
  693.                             if (tk_operation->def)
  694.                                free_op(tk_operation->op_name);
  695.                             else
  696.                                m_exit(F_DNDMAC,tk_operation->op_name);
  697.                             continue;
  698.                          case VARIABLE:
  699.                             free_var(tk_var->var_name);
  700.                             break;
  701.                          case OPCODE:
  702.                             tk_key->use=False;
  703.                             break;
  704.                          default:
  705.                             m_exit(M_NOVAR);
  706.                        }
  707.                     }
  708.                    break;
  709.                  }
  710.                 /*}}}  */
  711.                 /*{{{  defmodestring*/
  712.                 case DEFMODE:
  713.                  { unsigned char name[NAME_LG];
  714.                    unsigned char str[2][NAME_LG];
  715.                    int i;
  716.  
  717.                    if (used_modes==MODE_COUNT)
  718.                       m_exit(M_MANYMODES);
  719.                    /*{{{  read name*/
  720.                    name_parse(name,M_UMNAME,False);
  721.                    for (i=0;i!=used_modes;i++)
  722.                       if (!ustrcmp(tk_string,modenames[i]))
  723.                          m_exit(M_UMNAME);
  724.                    modenames[used_modes]=mstrcpy(tk_string);
  725.                    /*}}}  */
  726.                    /*{{{  scan the two string*/
  727.                    for (i=0;i<2;i++) {
  728.                      if (get_full_token()!=MACRO)
  729.                         m_exit(M_MSTR);
  730.                      ustrcpy(str[i],tk_string);
  731.                    }
  732.                    /*}}}  */
  733.                    write_ums_rc(used_modes++,str[0],str[1]);
  734.                    /*{{{  verbose?*/
  735.                    if (verbose_level>0)
  736.                       fprintf(stderr,F_DEFMOD,used_modes-1,str[0],str[1]);
  737.                    /*}}}  */
  738.                    break;
  739.                  }
  740.                 /*}}}  */
  741.                 /*{{{  start-list-editing*/
  742.                 case START_LIST:
  743.                    arg_list=True;
  744.                    break;
  745.                 /*}}}  */
  746.                 /*{{{  opcodes or default error*/
  747.                 case OPCODE:
  748.                    if (tk_key->num==O_TITLE_HIDE)
  749.                     { var_notitle=1;
  750.                       break;
  751.                     }
  752.                 default:
  753.                    goto pars_error;
  754.                 /*}}}  */
  755.               }
  756.             get_end_token:
  757.               end_parse(M_WANTEND);
  758.               break;
  759.             }
  760.             /*}}}  */
  761.            /*{{{  default=error*/
  762.            default:
  763.            pars_error:
  764.               m_exit(M_NOKCOMMAND);
  765.            /*}}}  */
  766.          }
  767.   err_pos_out=False;
  768.   /*}}}  */
  769.   /*{{{  test number of defined functions*/
  770.   if (mac_count==0x7fff)
  771.      m_exit(M_MUCH_FUN);
  772.   /*}}}  */
  773.   if (verbose_level>0)
  774.      fprintf(stderr,"-----------------\n");
  775.   /*{{{  check forward-declarations*/
  776.   { OP_LIST *op;
  777.  
  778.     op= &new_op;
  779.     while (op)
  780.        if (!op->def)
  781.           m_exit(F_DNDMAC,op->op_name);
  782.        else
  783.           op=op->next;
  784.   }
  785.   /*}}}  */
  786.   /*{{{  check mkbd-defines*/
  787.   check_k_modes();
  788.   /*}}}  */
  789.   /*{{{  write sets*/
  790.   if (!dest_mac)
  791.      writesets(rc.fp);
  792.   /*}}}  */
  793.   /*{{{  write keyboards*/
  794.   write_kbds();
  795.   /*}}}  */
  796.   put_consts();
  797.  
  798.   return(False);
  799. }
  800. /*}}}  */
  801.